package com.wholeintech.utils;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Toast;

import org.xutils.DbManager;
import org.xutils.x;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;

/**
 * Created by Lyle on 2016-01-19.
 */
public final class CommonUtil {
    private final static String TAG = CommonUtil.class.getSimpleName();
	
    public final static int THREAD_START = 0;
    public final static int THREAD_RUN = 1;
    public final static int THREAD_STOP = 2;
    
    public final static int OBJTOBYTE_CMD_POS = 28;	//对象转换成数组后的位置
    
    public static DbManager MyDbUtils() {
        DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
                .setDbName("MyDb.db")
                // 不设置dbDir时, 默认存储在app的私有目录.
                .setDbDir(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/database")) // "sdcard"的写法并非最佳实践, 这里为了简单, 先这样写了.
                .setDbVersion(1)
                .setDbOpenListener(new DbManager.DbOpenListener() {
                    @Override
                    public void onDbOpened(DbManager db) {
                        // 开启WAL, 对写入加速提升巨大
//                        db.getDatabase().enableWriteAheadLogging();
                    }
                })
                .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
                    @Override
                    public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
                        // TODO: ...
                        // db.addColumn(...);
                        // db.dropTable(...);
                        // ...
                        // or
                        // db.dropDb();
                    }
                });
        return x.getDb(daoConfig);
    }
    
    public static void MyDbUtilsClose() {
        try {
            MyDbUtils().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String bytesToHexString(byte[] src, int len) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }

        for (int i = 0; i < len; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase();
    }


    public static String bytesToHexString(byte[] src, int start,int len) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0 || src.length <(start+len)) {
            return null;
        }

        for (int i = start; i < (start + len) ; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase();
    }

    public static byte[] hex2byte(String hex) {
        hex = hex.toUpperCase();
        hex = hex.replace(" ", "");
        String digital = "0123456789ABCDEF";
        char[] hex2char = hex.toCharArray();
        byte[] bytes = new byte[hex.length() / 2];
        int temp;
        for (int i = 0; i < bytes.length; i++) {
            temp = digital.indexOf(hex2char[2 * i]) * 16;
            temp += digital.indexOf(hex2char[2 * i + 1]);
            bytes[i] = (byte) (temp & 0xff);
        }
        return bytes;
    }
    
    public static byte[] exchangebyte(byte[] b) {
    	byte[] bytes=new byte[b.length];
    	int i;
    	for(i=0; i<b.length; i++ )
    	{
    		bytes[i]=b[b.length-i-1];
    	}
    	return bytes;
    }
    
    public static byte[] mergebyte(byte[] a,byte[] b) {
        byte[] bytes = new byte[a.length+b.length];     
        System.arraycopy(a, 0, bytes, 0, a.length);
        System.arraycopy(b, 0, bytes, a.length, b.length);
        
        return bytes;
    }
    
    public static byte[] macbytes(String mac) {

        return exchangebyte(hex2byte(mac));
    }
    
    public static byte[] serialNobytes(String serialNo) {  	
        return exchangebyte(serialNo.getBytes());
    }
	
    public static byte[] getSpecbyte(byte[] data,int start,int len) {
    	byte bytes[]=new byte[len];
    	if(data.length<len+start)
    		return null;
    	System.arraycopy(data, start, bytes, 0, len);
    	return bytes;
    }
    
    public static boolean checkMacFormat(String mac) {
        if (mac.length() == 16) {
        	return true;
        } else {
            //Log.e(TAG, "MAC Len(16) Is Error:" + mac + ",Len:" + mac.length());
            return false;
        }
    } 
    
    /*** Add by hy,2017/03/17 ????MAC????: AABBCCDDEEFF ***/
    public static boolean WrdNetCheckMacFormat(String mac) {
        if (mac.length() == 12) {
        	return true;
        } else {
            //Log.e(TAG, "MAC Len(16) Is Error:" + mac + ",Len:" + mac.length());
            return false;
        }
    }
    
    /* 二进制无符号类型转换  */
    public static int getUnsignedByte(byte data){      //将data字节型数据转换为0~255 (0xFF 即BYTE)。
        return data&0x0FF ;
     }

     public static int getUnsignedByte(short data){      //将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。
           return data&0x0FFFF ;
     }       

    public static long getUnsignedIntt(int data){     //将int数据转换为0~4294967295 (0xFFFFFFFF即DWORD)。
        return data&0x0FFFFFFFF ;
     }  
    
    private static byte[] CRC8Table = {
            (byte) 0x00, (byte) 0x07, (byte) 0x0E, (byte) 0x09, (byte) 0x1C, (byte) 0x1B, (byte) 0x12, (byte) 0x15, (byte) 0x38, (byte) 0x3F, (byte) 0x36, (byte) 0x31, (byte) 0x24, (byte) 0x23, (byte) 0x2A, (byte) 0x2D,
            (byte) 0x70, (byte) 0x77, (byte) 0x7E, (byte) 0x79, (byte) 0x6C, (byte) 0x6B, (byte) 0x62, (byte) 0x65, (byte) 0x48, (byte) 0x4F, (byte) 0x46, (byte) 0x41, (byte) 0x54, (byte) 0x53, (byte) 0x5A, (byte) 0x5D,
            (byte) 0xE0, (byte) 0xE7, (byte) 0xEE, (byte) 0xE9, (byte) 0xFC, (byte) 0xFB, (byte) 0xF2, (byte) 0xF5, (byte) 0xD8, (byte) 0xDF, (byte) 0xD6, (byte) 0xD1, (byte) 0xC4, (byte) 0xC3, (byte) 0xCA, (byte) 0xCD,
            (byte) 0x90, (byte) 0x97, (byte) 0x9E, (byte) 0x99, (byte) 0x8C, (byte) 0x8B, (byte) 0x82, (byte) 0x85, (byte) 0xA8, (byte) 0xAF, (byte) 0xA6, (byte) 0xA1, (byte) 0xB4, (byte) 0xB3, (byte) 0xBA, (byte) 0xBD,
            (byte) 0xC7, (byte) 0xC0, (byte) 0xC9, (byte) 0xCE, (byte) 0xDB, (byte) 0xDC, (byte) 0xD5, (byte) 0xD2, (byte) 0xFF, (byte) 0xF8, (byte) 0xF1, (byte) 0xF6, (byte) 0xE3, (byte) 0xE4, (byte) 0xED, (byte) 0xEA,
            (byte) 0xB7, (byte) 0xB0, (byte) 0xB9, (byte) 0xBE, (byte) 0xAB, (byte) 0xAC, (byte) 0xA5, (byte) 0xA2, (byte) 0x8F, (byte) 0x88, (byte) 0x81, (byte) 0x86, (byte) 0x93, (byte) 0x94, (byte) 0x9D, (byte) 0x9A,
            (byte) 0x27, (byte) 0x20, (byte) 0x29, (byte) 0x2E, (byte) 0x3B, (byte) 0x3C, (byte) 0x35, (byte) 0x32, (byte) 0x1F, (byte) 0x18, (byte) 0x11, (byte) 0x16, (byte) 0x03, (byte) 0x04, (byte) 0x0D, (byte) 0x0A,
            (byte) 0x57, (byte) 0x50, (byte) 0x59, (byte) 0x5E, (byte) 0x4B, (byte) 0x4C, (byte) 0x45, (byte) 0x42, (byte) 0x6F, (byte) 0x68, (byte) 0x61, (byte) 0x66, (byte) 0x73, (byte) 0x74, (byte) 0x7D, (byte) 0x7A,
            (byte) 0x89, (byte) 0x8E, (byte) 0x87, (byte) 0x80, (byte) 0x95, (byte) 0x92, (byte) 0x9B, (byte) 0x9C, (byte) 0xB1, (byte) 0xB6, (byte) 0xBF, (byte) 0xB8, (byte) 0xAD, (byte) 0xAA, (byte) 0xA3, (byte) 0xA4,
            (byte) 0xF9, (byte) 0xFE, (byte) 0xF7, (byte) 0xF0, (byte) 0xE5, (byte) 0xE2, (byte) 0xEB, (byte) 0xEC, (byte) 0xC1, (byte) 0xC6, (byte) 0xCF, (byte) 0xC8, (byte) 0xDD, (byte) 0xDA, (byte) 0xD3, (byte) 0xD4,
            (byte) 0x69, (byte) 0x6E, (byte) 0x67, (byte) 0x60, (byte) 0x75, (byte) 0x72, (byte) 0x7B, (byte) 0x7C, (byte) 0x51, (byte) 0x56, (byte) 0x5F, (byte) 0x58, (byte) 0x4D, (byte) 0x4A, (byte) 0x43, (byte) 0x44,
            (byte) 0x19, (byte) 0x1E, (byte) 0x17, (byte) 0x10, (byte) 0x05, (byte) 0x02, (byte) 0x0B, (byte) 0x0C, (byte) 0x21, (byte) 0x26, (byte) 0x2F, (byte) 0x28, (byte) 0x3D, (byte) 0x3A, (byte) 0x33, (byte) 0x34,
            (byte) 0x4E, (byte) 0x49, (byte) 0x40, (byte) 0x47, (byte) 0x52, (byte) 0x55, (byte) 0x5C, (byte) 0x5B, (byte) 0x76, (byte) 0x71, (byte) 0x78, (byte) 0x7F, (byte) 0x6A, (byte) 0x6D, (byte) 0x64, (byte) 0x63,
            (byte) 0x3E, (byte) 0x39, (byte) 0x30, (byte) 0x37, (byte) 0x22, (byte) 0x25, (byte) 0x2C, (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x08, (byte) 0x0F, (byte) 0x1A, (byte) 0x1D, (byte) 0x14, (byte) 0x13,
            (byte) 0xAE, (byte) 0xA9, (byte) 0xA0, (byte) 0xA7, (byte) 0xB2, (byte) 0xB5, (byte) 0xBC, (byte) 0xBB, (byte) 0x96, (byte) 0x91, (byte) 0x98, (byte) 0x9F, (byte) 0x8A, (byte) 0x8D, (byte) 0x84, (byte) 0x83,
            (byte) 0xDE, (byte) 0xD9, (byte) 0xD0, (byte) 0xD7, (byte) 0xC2, (byte) 0xC5, (byte) 0xCC, (byte) 0xCB, (byte) 0xE6, (byte) 0xE1, (byte) 0xE8, (byte) 0xEF, (byte) 0xFA, (byte) 0xFD, (byte) 0xF4, (byte) 0xF3
    };

    public static byte getCheckSum(byte[] crcData,int len) {
        byte crc8 = 0;
        for (int i = 0; i < len; i++) {
            crc8 = CRC8Table[(crc8 ^ crcData[i]) & 0xff];
        }
        return crc8;
    }

    public static byte getSeekCheckSum(byte[] crcData,int start,int len) {

        byte crc8 = 0;
        for (int i = start; i < (start + len); i++) {
            crc8 = CRC8Table[(crc8 ^ crcData[i]) & 0xff];
        }
        return crc8;
    }

    public static byte getXorChecksum(byte[] xorData,int len) {
        byte xor = 0;

        for (int i = 0; i < len; i++) {
            xor = (byte)((xor ^ xorData[i]) & 0xff);
        }

        return xor;
    }

    public static byte getSeekXorChecksum(byte[] xorData,int start,int len) {
        byte xor = 0;

        for (int i = start; i < (start + len); i++) {
            xor = (byte)((xor ^ xorData[i]) & 0xff);
        }
        return xor;
    }
	public static void showDialog(Context context,String strMessage){
		Toast msg = Toast.makeText(context, strMessage, Toast.LENGTH_SHORT);
		msg.show();
	}
	
	public static void showDialog(Context context,int msgResourceId){
		String strMessage = context.getResources().getString(msgResourceId);
		Toast msg = Toast.makeText(context, strMessage, Toast.LENGTH_SHORT);
		msg.show();
	}
	
	
    /**
     * 对象转Byte数组
     * @param obj
     * @return
     */
    public static byte[] objectToByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
            objectOutputStream.flush();
            bytes = byteArrayOutputStream.toByteArray();

        } catch (IOException e) {
        	e.printStackTrace();
        } finally {
            if (objectOutputStream != null) {
                try {
                    objectOutputStream.close();
                } catch (IOException e) {
                	e.printStackTrace();
                }
            }
            if (byteArrayOutputStream != null) {
                try {
                    byteArrayOutputStream.close();
                } catch (IOException e) {
                	e.printStackTrace();
                }
            }

        }
        return bytes;
    }	

    /**
     * 设置当前盒子zigbee网关版本
     *
     * @return
     */
    public static boolean setZigbeeGWVersion(String strZigbeeGWVersion) {
        Process process_ip;
        try {
            process_ip = Runtime.getRuntime().exec("setprop persist.sys.ZigBeeGwVersion "+ strZigbeeGWVersion + "\n");
            //DataOutputStream os = new DataOutputStream(process_ip.getOutputStream());  
            //os.writeBytes("getprop persist.sys.ZigBeeGwVersion "+ strZigbeeGWVersion + "\n");  
            //os.writeBytes("setprop persist.sys.ZigBeeGwVersion GW20180511\n");
            //os.flush();  
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return true;
    }

    /**
     * 获取当前盒子Zigbee网关版本
     *
     * @return
     */
    public static String getZigbeeGWVersion() {
        String strZigbeeGWVersion = "0";
        BufferedReader input;
        byte[] stdout;
        Process process_ip;
        try {
            process_ip = Runtime.getRuntime().exec("getprop persist.sys.ZigBeeGwVersion");

            InputStreamReader lr_ip = new InputStreamReader(process_ip.getInputStream());
            input = new BufferedReader(lr_ip);
            String readLine = input.readLine();
            if (readLine != null) {
                stdout = readLine.getBytes();
                strZigbeeGWVersion = new String(stdout);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (strZigbeeGWVersion.trim().equals(""))
        	strZigbeeGWVersion = "0";

        return strZigbeeGWVersion;
    }
    
	/**
	 * 启动一个Activity
	 * @param context
	 * @param cls
	 */
	public static void startActivity(Context context,Class<?> cls){
		Intent intent = new Intent(context,cls);
		context.startActivity(intent);
	}
	
	/**
	 * 启动一个Activity
	 * @param context
	 * @param cls
	 */
	public static void startActivity(Context context,Class<?> cls,Bundle data){
		Intent intent = new Intent(context,cls);
		if(data!=null){
			intent.putExtras(data);
		}
		context.startActivity(intent);
	}

    /**
     * 发送广播消息
     * @param context
     * @param intent
     * @param boxId
     * @param devId
     * @param type
     */
    public static void sendBroadcastMsg(Context context, String intent, String boxId, String devId,
                                        int type, boolean isCtlLight8, ArrayList<String> subDevList) {
        Intent mIntent = new Intent(intent);

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date curDate = new Date(System.currentTimeMillis());
        String timeStr = formatter.format(curDate);

        mIntent.putExtra("boxId", boxId==null?"":boxId);
        mIntent.putExtra("deviceId", devId==null?"":devId);
        mIntent.putExtra("type", type+"");
        mIntent.putExtra("time", timeStr);

        if(isCtlLight8) {
            mIntent.putExtra("isCtlLight8", 1);
            mIntent.putStringArrayListExtra("subDevList",subDevList);
        }

        context.sendBroadcast(mIntent);
    }


    /**
     * ��ȡ��ǰZigBee��ԴIO״̬
     *
     * @return
     */
    public static int getZigBeeGWPowerIOStatus() {
        int intStatus = 0;
        File file = new File("proc/gpio_ctrl/rp_gpio_ctrl");
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            tempString = reader.readLine();
            if (tempString != null) {
                tempString = tempString.trim();
                if (!tempString.equals("")) {
                    intStatus = Integer.parseInt(tempString.substring(0, 1));
                }
            }

            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }

        //Log.d(TAG, "getZigBeeGWPowerIOStatus:" + intStatus);
        return intStatus;
    }

    /**
     * �ر�ϵͳ
     */
    public static void ZigBeeGWShutDown() {
        File blCtrlShut = new File("proc/gpio_ctrl/rp_gpio_ctrl");
        FileWriter fr;

        try {
            fr = new FileWriter(blCtrlShut);
            fr.write("10");
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * ����ϵͳ
     */
    public static void ZigBeeGWWakeUp() {
        File blCtrlWake = new File("proc/gpio_ctrl/rp_gpio_ctrl");
        FileWriter fr;

        try {
            fr = new FileWriter(blCtrlWake);
            fr.write("9");
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取当前的版本类型
     * @param context
     * @return
     */
    public static int getVersionType(Context context){
        int intVersionType = 1;//默认宏云版本
        Properties properties = PropertiesUtil.loadProperties(context);
        String strVerionType = properties.getProperty("VERSION_TYPE");
        if(strVerionType!=null && !strVerionType.equals("")){
            try {
                intVersionType = Integer.parseInt(strVerionType);
            }catch (Exception exception){
                exception.printStackTrace();
            }
        }

        return intVersionType;

    }

}
